(function($){
	
$.extend({
	pjax : function(options){
		options = $.extend({
			seletor : 'a[href!=""][href!="#"][target!="_blank"]:not([href^="javascript:"]):not([data-pjax-skip])', //要监控的选择器
			container : 'body', //要替换内容的容器
			success : null //容器设置内容后执行
		}, options);
		var support = window.history && window.history.pushState && window.history.replaceState &&
			!navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/);
		$(document).on('click', options.seletor, function(e){
			var _this = $(this), href = _this.attr('href'), title = _this.attr('title')||_this.text();
			if(href===location.href || !!_this.attr('data-pjax-skip'))return true;
			var state = {
				container : options.container,
				html : $(options.container).html(),
				title : document.title,
				cls : $('body').attr('class'),
				style : $('body').attr('style'),
				url : location.href
			};
			$.ajax({
				url : href,
				dataType : 'html',
				beforeSend : function(xhr){
					$(options.container).trigger('pjax.start', [ xhr, options ]);
					xhr && xhr.setRequestHeader('X-PJAX', true);
				},
				success : function(html){
					var matches = null;
					if(!title){
						matches = html.match(/<title>(.*?)<\/title>/i);
						if(matches)title = matches[1];
					};
					document.title = title;
					if(support){
						window.history.replaceState(state, '', '');
						window.history.pushState(state, title, href);
					}else{
						location.hash = href;
					};
					$('body').removeAttr('class').removeAttr('style');
					var cls = html.match(/<body.*?( class="([^"]+)")?[^>]*>/i)[2],
						style = html.match(/<body.*?( style="([^"]+)")?[^>]*>/i)[2];
					if(cls)$('body').addClass(cls);
					if(style)$('body').attr('style', style);
					
					html = html.replace(/<!doctype[^>]*>/ig, '').replace(/<\/?html[^>]*>/ig, '').replace(/<head>[\s\S]+?<\/head>/ig, '')
						.replace(/<\/?body[^>]*>/ig, '').replace(/<title>.*?<\/title>/ig, '');
					$(options.container).html(html);
					if($.isFunction(options.success))options.success.call($(options.container));
				},
				error : function(){
					location.href = href;
				},
				complete : function(xhr){
					$(options.container).trigger('pjax.end', [ xhr, options ]);
				}
			});
			e.preventDefault();
			return false;
		});
	}
});

window.onpopstate = function(e){
	if(e.state){
		var state = e.state;
		if(state.container && $(state.container).length){
			document.title = state.title;
			$('body').removeAttr('class').removeAttr('style');
			if(state.cls)$('body').addClass(state.cls);
			if(state.style)$('body').attr('style', state.style);
			$(state.container).html(state.html);
			if($.isFunction(state.success))state.success.call($(state.container));
		}
	}
};
	
})(jQuery);